#ifndef __BinaryTree__
#define __BinaryTree__

template<class type>
class node
{
private :
        node(){}
public :
        type data;
        node<type>* pLeft;
        node<type>* pRight;

        node(type data , node<type>* pRight , node<type>* pLeft) {
                this->data = data;
                this->pRight = pRight;
                this->pLeft = pLeft;
        }
};

template<class type>
class BinaryTree
{
public:
        node<type>* pRoot;
        int arrayCount;

        type* pLinearArray;
        BinaryTree();
        ~BinaryTree();
        void insertNode(type data);
        void deleteNode(type data);
        void findData(type& data , int& isFound);
        void print();
        int getCount();
        void clearAll();
        int merge(BinaryTree<type>* merge , BinaryTree<type>* left , BinaryTree<type>* right , type data);

        int operator<(BinaryTree<type> right) {
                return !( (this->pRoot->data)== (right.pRoot->data) || (this->pRoot->data) > (right.pRoot->data) );
        }
        int operator>(BinaryTree<type> right)
        {
                return !( (this->pRoot->data)== (right.pRoot->data) || (this->pRoot->data) < (right.pRoot->data) );
        }

protected : 
        void insert(node<type>*& pNode, type data); 
        void GetPredecessor(node<type>* pNode , type& data);
        void deleteThis(node<type>*& pNode, type data);
        void deleteThisNode(node<type>*& pNode); 

        void find(node<type>* pNode , type& data , int& isFound);

        void printNode(node<type>* pNode);

        int countNodes(node<type>* pNode);

        void destroy(node<type>*& pNode); 
};

#endif
